/*
 * debug.c
 *
 *  Created on: Dec 15, 2008
 *      Author: michael
 */

#include <comlib.h>

/****
 * Log msg to file
 * pFile which file log to write
 ***/
int Log(FILE *pFile, const char * pformat, ...)
{
	va_list _va_list;
	TIMESTRU timestru;
	char szBuf[MAXBUF];
	int nLen;
	if (pFile == NULL || pformat == NULL)
		return -1;/*invalid argument*/
	timestru = GetTime();
	nLen = sprintf(szBuf, " %04d.%02d.%02d %02d:%02d:%02d [%d]: ", timestru.nY,
			timestru.nM, timestru.nD, timestru.nH, timestru.nMin, timestru.nS,
			getpid());

	va_start(_va_list, pformat);
	nLen += vsprintf(szBuf + nLen, pformat, _va_list);
	va_end(_va_list);

	nLen += sprintf(szBuf + nLen, "\n");
	if (fputs(szBuf, pFile) != EOF && fflush(pFile) != EOF)
		return 0;
	return -2;
}

/****
 * Log msg to file which predefined (TRACE_FILE)
 ***/
int Trace(const char *pformat, ...)
{
	FILE *pf;
	int ret;
	char szBuf[MAXBUF];
	va_list _va_list;
	if (pformat == NULL)
		return -1;

	va_start(_va_list, pformat);
	vsprintf(szBuf, pformat, _va_list);
	va_end(_va_list);

	if ((pf = fopen(TRACE_FILE, "a")) != NULL)
	{
		ret = Log(pf, szBuf);
		fclose(pf);
		return ret;
	}
	return -1;
}

/****
 * Hex Log msg to file
 * pFile which file log to write
 * pData the begin address of the memory
 * nSize the number of bytes will be write to file
 ***/
int HexLog(FILE *pFile, void *pData, int nSize)
{
	char cLine[16], *pcData;
	char szBuf[MAXBUF + 1];
	int nPos, nLineSize, nLine, nLen, n, ret;
	if (pFile == NULL || pData == NULL)
		return -1;
//	ASSERT(pFile!=NULL&&pData!=NULL);
	pcData = (char *) pData;
	nLine = 1;
	nLen = sprintf(szBuf, "address[%#08X] size[%d]\n", (int)pData, nSize);
	for (nPos = 0; nPos < nSize; nLine++)
	{
		// avoid no enough data of the last line.
		nLineSize = min(nSize-nPos,16);
		memcpy(cLine, pcData + nPos, nLineSize);
		nPos += nLineSize;
		nLen += sprintf(szBuf + nLen, "[%02d]:", nLine);
		for (n = 0; n < nLineSize; n++)
		{
			/* space after the eight byte*/
			if (n == 8)
				nLen += sprintf(szBuf + nLen, " ");
			nLen += sprintf(szBuf + nLen, "%02X", cLine[n] & 0x00FF);
		}
		/* space the last line*/
		for (n = nLineSize; n < 16; n++)
		{
			if (n == 8)
				nLen += sprintf(szBuf + nLen, " ");
			nLen += sprintf(szBuf + nLen, " ");
		}

		nLen += sprintf(szBuf + nLen, ":");
		for (n = 0; n < nLineSize; n++)
		{
			if (!isprint(cLine[n]))
				cLine[n] = '.';
			nLen += sprintf(szBuf + nLen, "%c", cLine[n]);
		}
		nLen += sprintf(szBuf + nLen, "\n");
	}
	ret = Log(pFile, szBuf);
	return ret;
}

/****
 * Hex Log msg to file which predefined (TRACE_FILE)
 * pData the begin address of the memory
 * nSize the number of bytes will be write to file
 ***/
int HexTrace(void *pData, int nSize)
{
	FILE *pf;
	int ret;
	if ((pf = fopen(TRACE_FILE, "a")) != NULL)
	{
		ret = HexLog(pf, pData, nSize);
		fclose(pf);
		return ret;
	}
	return -1;
}

/****
 * verify the expr's condition
 * bStatus assert this value be TRUE, error ocurr if FALSE
 * pszInfo error msg write to file when error ocurr.
 * pszFile which file the error ocurr
 * nLine the line number of the pszFile error ocurr
 ***/
int Verify(int bStatus, const char *pszInfo, const char *pszFile, int nLine)
{
	FILE *pf;
	char szFileLine[128], szError[128];
	if (!bStatus)
	{
		memset(szFileLine, 0,sizeof(szFileLine));
		memset(szError, 0,sizeof(szError));

		if (errno != 0)
			sprintf(szError, "\t>%.64s\n", strerror(errno));
		if (pszFile == NULL)
		{
			strcpy(szFileLine, "\t>Invalid file name");
		} else
		{
			sprintf(szFileLine, "\t> In line %d file %.32s", nLine, pszFile);
		}
		if (pszInfo == NULL)
		{
			pszInfo = "";
		}
		pf = fopen(TRACE_FILE, "a");
		if (pf != NULL)
		{
			Log(pf, "%s[%d]\n%s%s", pszInfo, getpid(), szError, szFileLine);
			fclose(pf);
		}

	}
	return bStatus;
}

